package com.kaifamiao.tcp;
import java.io.*;
import java.net.*;
import java.nio.file.*;
import java.nio.file.WatchEvent.Kind;

public class Sender {
    public static void main(String[] args) throws IOException {
        final Path pathToWatch = Paths.get("/Users/linrui/a");
        final WatchService watchService = FileSystems.getDefault().newWatchService();
        pathToWatch.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE);

        while (true) {
            WatchKey key;
            try {
                key = watchService.take();
            } catch (InterruptedException ex) {
                return;
            }

            for (WatchEvent<?> event : key.pollEvents()) {
                Kind<?> kind = event.kind();
                Path changedPath = pathToWatch.resolve((Path) event.context());
                try (Socket socket = new Socket("localhost", 8080)) {
                    if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
                        recursiveSend(socket, changedPath);
                    } else if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
                        sendCommandAndPath(socket, "DELETE", changedPath);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            key.reset();
        }
    }

    private static void sendCommandAndPath(Socket socket, String command, Path path) throws IOException {
        try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream())) {
            dos.writeUTF(command);
            dos.writeUTF(path.toString().replace("/Users/linrui/a", ""));
            if (Files.isDirectory(path)) {
                dos.writeBoolean(true);
            } else {
                dos.writeBoolean(false);
                sendFile(socket, path);
            }
        }
    }

    private static void recursiveSend(Socket socket, Path path) throws IOException {
        sendCommandAndPath(socket, "ADD", path);
        if (Files.isDirectory(path)) {
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
                for (Path entry : stream) {
                    recursiveSend(socket, entry);
                }
            }
        }
    }

    private static void sendFile(Socket socket, Path file) throws IOException {
        try (DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
             FileInputStream fis = new FileInputStream(file.toFile())) {

            byte[] buffer = new byte[4096];
            dos.writeLong(Files.size(file));
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                dos.write(buffer, 0, bytesRead);
            }
        }
    }
}
